/*!
 * LocaleHelper.js is a small util for processing words with diacritique
 *
 * Author:  Matej Tymes
 * Date:    Fri May 06 2011 - 11:00
 *
 * No additional library required
 *
 */


function LocaleHelper() { // constructor

    // slovak, czech, german, polish, hungarian, spanish, french, italian, turkish, latvian, lithuanian
    // todo: not sure how to or if I should process german letter 'ß'
    var localizedCharList = "áäąàâæāéěęèêëēėíîïìıīįóôöőœòúůüűùûūųýÿÁÄĄÀÂÆĀÉĚĘÈÊËĒĖÍÎÏÌİĪĮÓÔÖŐŒÒÚŮÜŰÙÛŪŲÝŸčćçďğģķĺľłļňńñņŕřšśşťžźżČĆÇĎĞĢĶĹĽŁĻŇŃÑŅŔŘŠŚŞŤŽŹŻ";
    var latinCharList     = "aaaaaaaeeeeeeeeiiiiiiioooooouuuuuuuuyyAAAAAAAEEEEEEEEIIIIIIIOOOOOOUUUUUUUUYYcccdggkllllnnnnrrssstzzzCCCDGGKLLLLNNNNRRSSSTZZZ";

    this.charMap = new Array();
    for(var i = 0; i < localizedCharList.length; i++) {
        this.charMap[localizedCharList.charAt(i)] = latinCharList.charAt(i);
    }
}


LocaleHelper.prototype = {

    removeCharDiacritique : function(charToProcess) {

        var result = this.charMap[charToProcess];
        if ((result == undefined) || (result == null)) {
            result = charToProcess;
        }

        return result;
    },

    localeCharCompare : function(charA, charB) {

        var newCharA = this.removeCharDiacritique(charA);
        var newCharB = this.removeCharDiacritique(charB);

        return (newCharA == newCharB) ? 0 : ((newCharA < newCharB) ? -1 : 1);

        // removed: doesn't work on every browser
//        return charA.localeCompare(charB);
    },

    isLatinLetter : function(character) {
        return (character >= 'a' && character <= 'z') || (character >= 'A' && character <= 'Z');
    },


    // case sensitivity is used only when the words have the same letters (they are read the same way)
    diacritiqueComparison : function(textA, textB) {
        // todo: note: in Lithuanian alphabet the 'y' character is just before before 'j' - so this algorithm won't work properly

        var result = 0;

        var caseDiff = 0; // difference in case sensitiveness
        var minLength = Math.min(textA.length, textB.length);
        for (var i = 0; i < minLength; i++) {
            var charA = textA.charAt(i);
            var charB = textB.charAt(i);
            var lowerA = charA.toLocaleLowerCase();
            var lowerB = charB.toLocaleLowerCase();

            result = this.localeCharCompare(lowerA, lowerB);
            if (result == 0 && lowerA != lowerB) {
                result = (lowerA < lowerB) ? -1 : 1;
            }

            if (result == 0) {
                if (caseDiff == 0 && charA != charB) { // first most left difference in case is the only important one
                    caseDiff = (charA < charB) ? -1 : 1;
                }
            } else {
                break;
            }
        }

        if (result == 0) {
            if (textA.length != textB.length) {
                result = (textA.length < textB.length) ? -1 : 1;
            } else {
                result = caseDiff; // if the strings are identical let the case sensitive difference decide
            }
        }

        return result;
    },

    containsDiacritiqueText : function (fullText, searchText) {

        var textA = fullText;
        var textB = searchText;

        result = false;

        if (textB.length == 0) {
            result = true;
        } else if (textA.length >= textB.length) {
            for (var i = 0 ; i < textA.length - textB.length + 1; i++) {
                var found = true;

                for (var j = 0; j < textB.length; j++) {
                    var charA = textA.charAt(i + j).toLocaleLowerCase();
                    var charB = textB.charAt(j).toLocaleLowerCase();

                    if (charA != charB) {
                        if (this.localeCharCompare(charA, charB) != 0) {
                            found = false;
                            break;
                        } else if (!this.isLatinLetter(charB)) {
                            found = false;
                            break;
                        }
                    }
                }

                if (found == true) {
                    result = true;
                    break;
                }
            }
        }

        return result;
    }
};


var localeHelper = new LocaleHelper();
